package com.zhm.demo.modbus;

import com.ghgande.j2mod.modbus.Modbus;
import com.ghgande.j2mod.modbus.ModbusException;
import com.ghgande.j2mod.modbus.procimg.*;
import com.ghgande.j2mod.modbus.slave.ModbusSlave;
import com.ghgande.j2mod.modbus.slave.ModbusSlaveFactory;
import com.ghgande.j2mod.modbus.util.SerialParameters;

public class ModbusRTUServer {
    public static void main(String[] args) {
        // 简单添加几个测试数据

        SimpleProcessImage spi = new SimpleProcessImage();
        // 输入寄存器
        //输入寄存器（Input Register）是只读的寄存器，每个寄存器占用两个字节。常用于读取设备的测量值或状态信息
        spi.addInputRegister(0, new SimpleInputRegister(44));
        spi.addInputRegister(2, new SimpleInputRegister(462));


        // 线圈状态
        //线圈寄存器（Coil）用于表示开关量，每个bit对应一个信号的开关状态。线圈寄存器既可以读也可以写
        spi.addDigitalOut(1, new SimpleDigitalOut(true));
        spi.addDigitalOut(2, new SimpleDigitalOut(false));
        spi.addDigitalOut(3, new SimpleDigitalOut(true));
        spi.addDigitalOut(4, new SimpleDigitalOut(false));
        spi.addDigitalOut(5, new SimpleDigitalOut(true));
        spi.addDigitalOut(6, new SimpleDigitalOut(false));
        spi.addDigitalOut(7, new SimpleDigitalOut(true));
        spi.addDigitalOut(8, new SimpleDigitalOut(false));


        // 输入状态
        //离散输入寄存器（Discrete Input）是只读的寄存器，每个bit表示一个开关量的输入状态。常用于读
        spi.addDigitalIn(1, new SimpleDigitalIn(true));
        spi.addDigitalIn(2, new SimpleDigitalIn(true));
        spi.addDigitalIn(3, new SimpleDigitalIn(false));
        spi.addDigitalIn(4, new SimpleDigitalIn(true));
        spi.addDigitalIn(5, new SimpleDigitalIn(true));
        spi.addDigitalIn(6, new SimpleDigitalIn(true));
        spi.addDigitalIn(7, new SimpleDigitalIn(false));
        spi.addDigitalIn(8, new SimpleDigitalIn(true));


        //保持寄存器（Holding Register）用于存储具体的数据量，每个寄存器占用两个字节。保持寄存器既可以读也可以写，常用于存储设备的配置参数或状态信息
        // 保持寄存器
        spi.addRegister(new SimpleRegister(200));
        spi.addRegister(new SimpleRegister(99));


        // RTU串口参数配置
        SerialParameters serialParams = new SerialParameters();
        serialParams.setPortName("COM6"); // Windows串口名称，根据实际设备修改
        serialParams.setBaudRate(9600);   // 波特率
        serialParams.setDatabits(8);      // 数据位
        serialParams.setStopbits(1);      // 停止位
        serialParams.setParity("NONE");   // 校验位
        // 从站Id
        int unitId = 1;

        try {
            ModbusSlave slave = ModbusSlaveFactory.createSerialSlave(serialParams);
            slave.addProcessImage(unitId, spi);
            // 启动从站服务
            slave.open();

        } catch (ModbusException e) {
            // 处理异常...
            //...
            throw new RuntimeException(e);
        }

    }
}

